#include "thread.hpp"
#include "mutex.hpp"
#include "cond.hpp"
#include <vector>
#include <queue>

namespace ThreadPoolModule
{
    using namespace ThreadModule;
    using namespace MutexModule;
    using namespace CondModule;

    const static int DEFSIZE = 5;

    template <typename T>
    class ThreadPool
    {
    private:
        // 唤醒一个进程
        void Signal()
        {
            _cond.Signal();
            LOG((const int)LogLevel::DEBUG) << "唤醒一个的休眠线程";
        }

        // 唤醒全部进程
        void Broadcast()
        {
            _cond.Broadcast();
            LOG((const int)LogLevel::DEBUG) << "唤醒所有的休眠线程";
        }

    
        ThreadPool(const int num = DEFSIZE)
            : _num(num)
        {
            for (int i = 0; i < _num; i++)
            {
                _threadPool.emplace_back([this]()
                                         { 
                    LOG((const int)LogLevel::DEBUG) << "正在执行lamda回调！";
                    task_running(); });
            }
        }

        ThreadPool(const ThreadPool<T>& ) = delete;
        ThreadPool& operator=(ThreadPool<T>& ) = delete;

    public:
        static ThreadPool&  GetInstance()
        {
            GuardMutex GMutex(_mutex);
            if(_ptr == nullptr)
            {
                _ptr = new ThreadPool();
            }
            return *_ptr;
        }    

        void Start()
        {
            _isRun = true;
            for (int i = 0; i < _num; i++)
            {
                _threadPool[i].Start();
            }
        }

        void Join()
        {
            for (int i = 0; i < _num; i++)
            {
                _threadPool[i].Join();
            }
        }

        // 项任务队列压入指定任务
        void Equeue(T in)
        {
            if (_isRun)
            {
                GuardMutex mutex(_lock);
                _task_queue.push(in);
                if (_sleep_num == _num)
                {
                    Signal();
                }
            }
        }

        // 任务完成后，停止线程池。
        void Stop()
        {
            if (_isRun == false)
                return;
            _isRun = false;
            Broadcast();
        }

        // 每个线程执行的函数都会转接到这里
        void task_running()
        {
            char name[128];
            pthread_getname_np(pthread_self(), name, sizeof(name));
            LOG((const int)LogLevel::DEBUG) << "线程" << name << "开始运行";
            T task;
            while (true)
            {
                {
                    GuardMutex mutex(_lock);
                    while (_task_queue.empty() && _isRun)
                    {
                        _sleep_num += 1;
                        LOG((const int)LogLevel::DEBUG) << "线程" << name << "进入休眠";
                        _cond.Wait(_lock);
                        LOG((const int)LogLevel::DEBUG) << "线程" << name << "退出休眠";
                        _sleep_num -= 1;
                    }
                    if (_task_queue.empty() && !_isRun)
                    {
                        // 等待线程？
                        LOG((const int)LogLevel::DEBUG) << "线程" << name << "退出运行";
                        break;
                    }
                    task = _task_queue.front();
                    _task_queue.pop();
                }
                task();
            }
        }

    private:
        std::vector<Thread<T>> _threadPool;
        size_t _num;       // 线程创建的个数
        size_t _sleep_num = 0; // 休眠的线程数量

        std::queue<T> _task_queue;
        bool _isRun = false;
        Cond _cond;
        Mutex _lock;

        static ThreadPool<T>* _ptr;
        static Mutex _mutex;
    };
    template <typename T>
    ThreadPool<T>* ThreadPool<T>::_ptr = nullptr;
    template <typename T>
    Mutex ThreadPool<T>::_mutex;
}